package com.hsy.swu.hsyutils

import android.graphics.Typeface
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.widget.LinearLayoutCompat
import androidx.core.view.children
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelStoreOwner
import androidx.viewbinding.ViewBinding
import java.lang.reflect.Modifier
import java.lang.reflect.ParameterizedType

const val TAG = "hsyLifeCycleTag"

internal fun <T> Any.getGenericsActualClass(clazz: Class<*>): Class<T>? {
    // 获取泛型类父类
    val genericsSuperClass = javaClass.genericSuperclass
    // 如果父类不是泛型类型，返回 null
    if (genericsSuperClass !is ParameterizedType) {
        return null
    }
    // 获取泛型类参数的所有实际类型
    val actualTypeArguments = genericsSuperClass.actualTypeArguments
    // 遍历所有泛型类参数
    actualTypeArguments.forEach {
        if (it is Class<*> && clazz.isAssignableFrom(it)) { // 如果不是泛型类且能赋值，返回
            return it as Class<T>
        } else if (it is ParameterizedType) { // 如果是泛型类
            val rawType = it.rawType
            if (rawType is Class<*> && clazz.isAssignableFrom(rawType)) { // 如果不是泛型类且能赋值，返回
                return rawType as Class<T>
            }
        }
    }
    return null
}

internal fun <VB : ViewBinding> Any.createViewBinding(layoutInflater: LayoutInflater): VB? {
    val actualGenericsClass = getGenericsActualClass<VB>(ViewBinding::class.java)
        ?: throw NullPointerException("找不到${javaClass.name}的泛型父类")
    var viewBinding: VB? = null
    try {
        val inflateMethod =
            actualGenericsClass.getDeclaredMethod("inflate", LayoutInflater::class.java)
        viewBinding = inflateMethod.invoke(null, layoutInflater) as VB
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return viewBinding
}

internal fun <VM : HsyViewModel> Any.createViewModel(owner: ViewModelStoreOwner): VM {
    if (!(HsyActivity::class.java.isAssignableFrom(javaClass)
                || HsyFragment::class.java.isAssignableFrom(javaClass))
    ) {
        throw IllegalStateException("${javaClass.name}不能这样创建 HsyViewModel对象")
    }
    val actualGenericsClass = getGenericsActualClass<VM>(HsyViewModel::class.java)
        ?: throw NullPointerException("找不到${javaClass.name}的泛型父类")
    if (Modifier.isAbstract(actualGenericsClass.modifiers)) {
        throw IllegalStateException("抽象类${actualGenericsClass}不能实例化")
    }
    return ViewModelProvider(owner)[actualGenericsClass]
}

var FONT: Typeface? = null

fun ViewBinding.setFont() {
    (root as ViewGroup).setFont()
}

fun ViewGroup.setFont() {
    forEachChild {
        if (it is TextView) {
            it.setFont()
        }
    }
}

fun TextView.setFont() {
    if (FONT == null) { // 第一次则创建字体资源
        FONT = Typeface.createFromAsset(context.assets, "font/cn1.ttf")
    }
    typeface = FONT
}

private fun ViewGroup.forEachChild(action: (View) -> Unit) {
    children.forEach {
        action(it)
        if (it is ViewGroup) {
            it.forEachChild(action)
        }
    }
}

fun LinearLayoutCompat.addItem(binding: ViewBinding) {
    binding.setFont()
    addView(binding.root)
}